home *** CD-ROM | disk | FTP | other *** search
- // txscroll.cpp: Scrollable window class methods
-
- #include <math.h>
- #include "txscroll.h"
-
- // -------------------- ScrollFrame Methods --------------------
-
- // Correction: pg 294, Cp passed by reference, not by
- // pointer as in book
- ScrollFrame::ScrollFrame(BarOrient Orient, ColorPak &Cp)
- // Initializes a scroll bar's frame object.
- : Tfso(0x00, 0x00, Cp)
- {
- Orientation = Orient;
- }
-
- void ScrollFrame::SetSize(int W, int H)
- // The size (W,H) is interpreted to be the interior size. The
- // other sizes are based off of it. Dep}ing on the orientation,
- // one of the sizes is ignored.
- {
- if (Orientation == HzOrient) {
- Interior->SetSize(W, 1); // Height ignored
- Frame->SetSize(W+2, 1);
- Overall->SetSize(W+2, 1);
- }
- else {
- Interior->SetSize(1, H); // Width ignored
- Frame->SetSize(1, H+2);
- Overall->SetSize(1, H+2);
- }
- }
-
- void ScrollFrame::SetLocn(int Xl, int Yl)
- // Set the upper left hand corner location of the frame.
- // The location is interpreted to be that of the frame
- // rectangle.
- {
- Frame->SetLocn(Xl, Yl);
- Overall->SetLocn(Frame->Xul, Frame->Yul);
- if (Orientation == HzOrient)
- Interior->SetLocn(Frame->Xul+1, Frame->Yul);
- else Interior->SetLocn(Frame->Xul, Frame->Yul+1);
- }
-
- void ScrollFrame::DrawFrame(char, char)
- // The frame is just two arrows
- {
- if (Orientation == HzOrient) {
- Frame->HzWrt(0, 0, "\x1b", 0x70); // Left arrow
- Frame->HzWrt(Frame->Wd-1, 0, "\x1a", 0x70); // Right arrow
- }
- else {
- Frame->HzWrt(0, 0, "\x18", 0x70); // Up arrow
- Frame->HzWrt(0, Frame->Ht-1, "\x19", 0x70); // Down arrow
- }
- }
-
- // -------------------- Slider Methods ----------------------
-
- void Slider::Draw(void)
- // Draws a single character for the slider button
- {
- Panel->Interior->HzWrtB(0, 0, "\xb1");
- }
-
- void Slider::OnMouseDown(MsgPkt &M)
- // Call BorderHandler to move slider object whenever mouse is
- // pressed while on the slider
- {
- SwitchFocus(M);
- BorderHandler(M);
- }
-
- void Slider::Move(int X, int Y)
- // Move to new absolute coordinates. Send a message to the
- // scroll bar indicating its new position.
- {
- Wso::Move(X, Y);
- ((ScrollBar *)Base)->SendScrollPosn();
- }
-
- void Slider::OnKeyStroke(MsgPkt &M)
- // Send keystrokes detected while Slider is active to the scroll bar
- {
- Base->OnKeyStroke(M);
- }
-
- // --------------------- ScrollBar Methods ---------------------
-
- // Correction: pg 295, Cp passed by reference, not
- // by pointer as in book
- ScrollBar::ScrollBar(BarOrient Orient, ColorPak &Cp)
- // Initialize ScrollBar to use a ScrollFrame frame. Allocate
- // Slider object.
- : Iso(new ScrollFrame(Orient, Cp))
- {
- Slide = new Slider(Cp);
- Slide->SetSize(1, 1); // Always one texel big
- DelayCntr = 0; DelayLimit = 50; // Default delay
- InhibitMessage = False;
- }
-
- void ScrollBar::Draw()
- // Draw the patterned interior of the scroll bar
- {
- Iso::Draw();
- Panel->Clear(176, 0); // A patterned interior
- }
-
- void ScrollBar::Redraw()
- // Call default redraw action, then redraw the slider
- {
- Iso::Redraw();
- Slide->Redraw();
- }
-
- void ScrollBar::Open(Iso *B, int X, int Y)
- // Open the scrollbar, and then open the slider on top of it
- {
- Iso::Open(B, X, Y);
- Slide->Open(this, 0, 0);
- }
-
- void ScrollBar::BorderHandler(MsgPkt &M)
- // Mouse is on one of the arrows. Send a simulated keypress to the
- // scroll bar's base corresponding to which arrow is selected.
- {
- ScrollFrame *Sf = (ScrollFrame *)Panel;
- MsgPkt FakeMsg = NullMsg;
-
- FakeMsg.Focus = Base;
- if (Sf->Orientation == HzOrient) {
- if (M.Mx == Sf->Frame->Xul) { // Mouse on left arrow
- FakeMsg.Code = LeftKey; // Act like key was pressed
- Base->Dispatch(FakeMsg);
- }
- else if (M.Mx == Sf->Frame->Xlr) { // On right arrow
- FakeMsg.Code = RightKey;
- Base->Dispatch(FakeMsg);
- }
- }
- else {
- if (M.My == Sf->Frame->Yul) { // On up arrow
- FakeMsg.Code = UpKey;
- Base->Dispatch(FakeMsg);
- }
- else if (M.My == Sf->Frame->Ylr) { // On Down arrow
- FakeMsg.Code = DownKey;
- Base->Dispatch(FakeMsg);
- }
- }
- }
-
- void ScrollBar::OnMouseDown(MsgPkt &M)
- // Mouse is pressed when it is within the scroll bar.
- // Move the slider to that location.
- {
- if (Panel->OnInterior(M.Mx, M.My)) {
- Slide->Move(M.Mx, M.My);
- // Need to to this so you can leave the mouse button down
- // and still move.
- Slide->OnMouseDown(M);
- }
- else if (Panel->OnBorder(M.Mx, M.My)) BorderHandler(M);
- DelayCntr = 0; // Start count over
- }
-
- void ScrollBar::OnMouseStillDown(MsgPkt &M)
- // Mouse is still pressed on one of the scroll bar arrows.
- // If the DelayCntr has reached DelayLimit, then update
- // the slider position.
- {
- DelayCntr++;
- if (DelayCntr > DelayLimit) {
- if (Panel->OnBorder(M.Mx, M.My)) {
- BorderHandler(M);
- }
- DelayCntr = 0;
- }
- }
-
- void ScrollBar::OnKeyStroke(MsgPkt &M)
- // Send keystrokes to base window.
- {
- Base->OnKeyStroke(M);
- }
-
- void ScrollBar::SendScrollPosn(void)
- // Send a message to the base window of the scroll bar indicating its
- // position. The location of the slider in the scroll bar is encoded
- // to be a number between 0 and 10000 where a value of 10000
- // indicates that the slider is at full-scale.
- {
- int Ip;
- float Rp;
- MsgPkt M;
- Rso *Pint = Panel->Interior;
-
- if (InhibitMessage) return;
- M.Focus = Base;
-
- if (((ScrollFrame *)Panel)->Orientation == HzOrient) {
- // Compute relative position of slider to sliderbar
- Ip = Slide->Panel->Frame->Xul - Pint->Xul;
- if (Pint->Wd == 1)
- Rp = 0.0;
- else Rp = float(Ip) / float(Panel->Interior->Wd-1);
- M.Code = HzScrollMove; // M.RtnCode = Idle assumed
- M.Mx = floor(Rp * 10000.0); M.My = 0;
- }
- else { // Object is a vertical scroll bar
- Ip = Slide->Panel->Frame->Yul - Pint->Yul;
- if (Pint->Ht == 1)
- Rp = 0.0;
- else Rp = float(Ip) / float(Panel->Interior->Ht-1);
- M.Code = VtScrollMove; // M.RtnCode = Idle assumed
- M.Mx = 0; M.My = floor(Rp * 10000.0);
- }
- Base->Dispatch(M);
- }
-
-
- void ScrollBar::RcvScrollPosn(float P, BarOrient Which)
- // This method takes the number P, between 0.0 and 1.0, and
- // causes the Slider to move to the appropriate position.
- {
- int NewPos;
-
- if (Which == HzOrient) {
- // Compute relative position to move slider within slidebar
- NewPos = ceil(P * ((float)Panel->Interior->Wd-1));
- InhibitMessage = True;
- // Prevent Move from s}ing message back
- Slide->Move(Panel->Interior->Xul+NewPos,Panel->Interior->Yul);
- InhibitMessage = False;
- }
- else {
- // Compute relative position to move slider within slidebar
- NewPos = ceil(P * (float)(Panel->Interior->Ht-1));
- InhibitMessage = True;
- Slide->Move(Panel->Interior->Xul,NewPos+Panel->Interior->Yul);
- InhibitMessage = False;
- }
- }
-
- // --------------- Abstract Scroll Window Methods ----------------
-
- // Correction: Pg 298, Cp passed by reference, not by
- // pointer as in book
- Swso::Swso(int Fa, ColorPak &Cp)
- // Initialize Swso object by setting its border and allocating
- // the nested scroll bar objects.
- : Wso(0x11, Fa, Cp)
- {
- HzSlide = new ScrollBar(HzOrient, Cp);
- // Set True so can draw slider bars on border of window
- HzSlide->ClipToFrame = True;
- VtSlide = new ScrollBar(VtOrient, Cp);
- VtSlide->ClipToFrame = True;
- }
-
- void Swso::SetSize(int W, int H)
- // Set the size of the Swso object and the nested scroll bars.
- // Note: we have to relocate the scroll bars too. SetLocn has
- // no way of knowing they need to be relocated if the window
- // is resized.
- {
- Wso::SetSize(W, H);
- HzSlide->SetSize(W-2, 1);
- HzSlide->SetLocn(1, Panel->Frame->Ht-1, Relc);
- VtSlide->SetSize(1, H-2);
- VtSlide->SetLocn(Panel->Frame->Wd-1, 1, Relc);
- }
-
- void Swso::Stretch(int W, int H)
- // Stretch a scroll window. We must fake out the stretch
- // algorithm by setting the scroll bars to a minimum size
- // temporarily, otherwise, we can't make the window smaller.
- {
- HzSlide->SetSize(1,1);
- VtSlide->SetSize(1,1);
- Wso::Stretch(W,H);
- }
-
- void Swso::Open(Iso *B, int X, int Y)
- // Open Swso object and the two nested scroll bars
- {
- Wso::Open(B, X, Y);
- HzSlide->Open(this, 1, Panel->Frame->Ht-1);
- VtSlide->Open(this, Panel->Frame->Wd-1, 1);
- }
-
- void Swso::Redraw(void)
- // Redraw the window plus scroll bars
- {
- Wso::Redraw();
- HzSlide->Redraw();
- VtSlide->Redraw();
- }
-
- void Swso::Prompt(void)
- // We don't want to prompt Swso object because this would
- // overwrite the scroll bars, so we'll skip back two levels
- // in the hierarchy and call Iso's prompter
- {
- Iso::Prompt();
- }
-
- void Swso::UnPrompt(void)
- // We don't want to call Wso's prompter, since it would
- // overwrite the scroll bars, so we'll skip back two
- // levels in the hierarchy and call Iso's prompter
- {
- Iso::UnPrompt();
- }
-
- void Swso::Dispatch(MsgPkt &M)
- // Trap for ScrollMove event codes passed to the Swso object. These
- // events cause the scroll window to update what it displays.
- {
- if (M.Code == HzScrollMove) {
- RcvScrollPosn(float(M.Mx) / 10000.0, HzOrient);
- M.RtnCode = M.Code = Idle;
- }
- else if (M.Code == VtScrollMove) {
- RcvScrollPosn(float(M.My) / 10000.0, VtOrient);
- M.RtnCode = M.Code = Idle;
- }
- else Wso::Dispatch(M);
- }
-
-
-